package com.jdjc.suject.domin.util;

import com.alibaba.fastjson.JSON;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * 本地缓存工具类
 */
@Component
public class CacheUtil<K, V> {
    //定义了一个本地缓存实例，使用Guava库的CacheBuilder来构建
    private Cache<String, String> localCache = CacheBuilder.newBuilder()
            .maximumSize(5000) // 设置缓存的最大条目数为5000。
            .expireAfterWrite(10, TimeUnit.SECONDS) // 设置缓存条目在写入后10秒过期。
            .build();

    // 定义一个List类型的泛型方法，用于获取本地缓存
    public List<V> getResult(String cacheKey, Class<V> clazz, Function<String, List<V>> function) {
        List<V> resultList = new LinkedList<>();
        // 尝试从本地缓存中获取与缓存键相关联的值。
        String content = localCache.getIfPresent(cacheKey);
        if (content != null) {
            // 将缓存中的内容（JSON字符串）解析为指定类型的列表。
            resultList = JSON.parseArray(content, clazz);
        } else {
            // 如果缓存中没有找到与缓存键相关联的值。// 调用传入的函数来计算结果。
            resultList = function.apply(cacheKey);
            if (resultList != null) {
                // 将结果转换为JSON字符串，并存储在本地缓存中。
                localCache.put(cacheKey, JSON.toJSONString(resultList));
            }
        }
        return resultList;
    }


    public <K, V> Map<K, V> getMapResult(String cacheKey, Class<V> clazz, Function<String, List<V>> function, Function<V, K> keyExtractor) {
        // 尝试从本地缓存中获取与缓存键相关联的值。
        String content = localCache.getIfPresent(cacheKey);
        List<V> resultList; // 用于存储结果列表的变量。
        if (content != null) {
            // 如果缓存中找到了与缓存键相关联的值，将缓存中的内容（JSON字符串）解析为指定类型的列表。
            resultList = JSON.parseArray(content, clazz);
        } else {
            // 如果缓存中没有找到与缓存键相关联的值，调用传入的函数来计算结果。
            resultList = function.apply(cacheKey);
            if (resultList != null) {
                // 将结果转换为JSON字符串，并存储在本地缓存中。
                localCache.put(cacheKey, JSON.toJSONString(resultList));
            }
        }

        // 创建一个HashMap实例，用于存储结果映射表。
        Map<K, V> resultMap = new HashMap<>();
        // 遍历结果列表，使用keyExtractor函数从每个结果对象中提取键，并将键和对象添加到映射表中。
        for (V item : resultList) {
            resultMap.put(keyExtractor.apply(item), item);
        }

        // 返回结果映射表。
        return resultMap;
    }
}
